﻿/* ============================================================================
(c) Copyright 2012 Hewlett-Packard Development Company, L.P.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights to
use, copy, modify, merge,publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
============================================================================ */
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using HPCloud.Objects.DataAccess;
using HPCloud.Objects.Domain.Compute;
using HPCloud.Test;
using System.Threading;
using HPCloud.Objects.Domain.Compute.Servers;
using HPCloud.Objects.Utility;
using HPCloud.Objects.Domain.Compute.Servers.Actions;
using System.IO;
using HPCloud.Objects.Domain.Compute.Security;
using HPCloud.Objects.Test.Unit_Test.Compute;
using HPCloud.Objects.DataAccess.Compute;

namespace HPCloud.Objects.Test
{
    [TestClass]
    public class ServerTest : BaseUnitTest
    {
        public string _testServerId;

        #region Properties
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        private string TestServerId
        {
            get
            {
                return this.Context.Settings.TestServerId;
            }
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        private string TestImageId
        {
            get
            {
                return this.Context.Settings.TestImageId;
            }
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        private string TestFlavorId
        {
            get
            {
                return this.Context.Settings.TestFlavorId;
            }
        }
        #endregion
        #region Test Methods
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_Metadata_Add()       
        {
            // Assign metadata elements to server, save then delete the server..

            MetaData md = new MetaData();
            md.Add("key1", "value1");
            md.Add("key2", "value2");

            IServerRepository repository =  this.Factory.CreateServerRepository();
            MetaData result = repository.SetMetadata(md, this.TestServerId);
          
            Assert.IsTrue(result.Count > 0);
        }
//=========================================================================================
/// <summary>
/// Creates a test server, adds metadata to it, deletes that metadata, then cleans up.
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_Metadata_Delete()
        {
            // Assign metadata elements to server, save then delete the server..

            MetaData md = new MetaData();
            md.Add("key1", "value1");
            md.Add("key2", "value2");

            IServerRepository repository = this.Factory.CreateServerRepository();
            MetaData result              = repository.SetMetadata(md, this.TestServerId);

            repository.DeleteMetadata(this.TestServerId, "key1");
            Server testServer = repository.GetServer(this.TestServerId);

            Assert.IsFalse(testServer.MetaData.Where(s => s.Key == "key1").Any());
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Servers_GetLog()
        {
            GetServerLogAction action = new GetServerLogAction();
            action.ServerId           =  "203736";
            action.Length             = "400";
            Log log                   = this.Factory.CreateServerRepository().GetServerLog(action);
            //Assert.IsTrue(servers.Count > 0);
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Servers_GetAdminPassword()
        {
            GetServerLogAction action = new GetServerLogAction();
            action.ServerId = "225224";
            action.Length = "400";
            Log log = this.Factory.CreateServerRepository().GetServerLog(action);


            string pw = log.ExtractAdminPassword(@"e:\travis\logtest.pem");
            //Assert.IsTrue(servers.Count > 0);
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Servers_GetAll()
        {          
            List<Server> servers  = this.Factory.CreateServerRepository().GetServers();
            Assert.IsTrue(servers.Count > 0);
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_Update()
        {
            IServerRepository repository = this.Factory.CreateServerRepository();
            Server server                = repository.GetServer(this.TestServerId);
            string tempName              = Guid.NewGuid().ToString();
            server.Name                  = "Update  Test";            
            
            repository.UpdateServer(server);
            server = repository.GetServer(this.TestServerId);

            Assert.IsTrue(server.Name == "Update  Test");

            // Clean up

            server.Name = tempName;
            repository.UpdateServer(server);
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_TestRDPClient()
        {
            RDPClient client = new RDPClient();
            client.Address = "15.184.100.243";
            client.Username = "Administrator";
            client.Password = "awefae";
            client.LaunchClient();
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        
        public void Server_TestCredentialManager()
        {
            //HPCloud.Client.Powershell.Utility.CredentialListManager manager = new HPCloud.Client.Powershell.Utility.CredentialManager();
            //manager.SetPassword("222", "password");

            
        }
//=========================================================================================
/// <summary>
/// Creates a single Server with Meta-data based on an existing Image and Flavor definition.
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_SaveWindowsInstance()
        {
            // Create a Windows instance..

            NewServer server  = new NewServer();
            server.Name       = "WIB" + Guid.NewGuid().ToString();
            server.AccessIPv4 = "0.0.0.0";
            server.FlavorRef  = this.TestFlavorId;
            server.ImageRef   = this.TestImageId;
            server.KeyName    = "logtest";

            WindowsInstanceBuilder builder = new WindowsInstanceBuilder(this.Factory, this.Settings);
            builder.CreateInstance(server);


            
            //SecurityGroupAssignment assignment = new SecurityGroupAssignment();
            //assignment.Name = "rdp";

            //server.SecurityGroups.Add(assignment);
                        
            //IServerRepository repository = this.Factory.CreateServerRepository();
            //Server result                = repository.SaveServer(server);

            //// Retreive the Instance Log..
            
            //GetServerLogAction action = new GetServerLogAction();
            //action.ServerId           = result.Id;
            //Log log                   = repository.GetServerLog(action);
            
            //// Extract the randomly generated Admin PW..
            
            //string password = log.ExtractAdminPassword(this.Context.Settings.KeyStoragePath + @"\logtest.pem");

            //// Clean up. 

            //repository.DeleteServer(result.Id);

            //Assert.IsNotNull(result.Image);
            //Assert.IsNotNull(result.Flavor);
            //Assert.IsTrue (result.MetaData.Count > 0);
        }
//=========================================================================================
/// <summary>
/// Creates a single Server with Meta-data based on an existing Image and Flavor definition.
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_Save_WithMetadata()
        {
            NewServer server  = new NewServer();
            server.Name       = Guid.NewGuid().ToString();
            server.AccessIPv4 = "0.0.0.0";
            server.FlavorRef  = this.TestFlavorId;
            server.ImageRef   = this.TestImageId;

            MetaData md = new MetaData();
            md.Add("key1", "value1");
            md.Add("key2", "value2");
           // server.MetaData = md;
            
            IServerRepository repository = this.Factory.CreateServerRepository();
            Server result                = repository.SaveServer(server);

            repository.DeleteServer(result.Id);

            Assert.IsNotNull(result.Image);
            Assert.IsNotNull(result.Flavor);
            Assert.IsTrue (result.MetaData.Count > 0);
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_Delete()
        {
            // Setup a test server..

            NewServer server  = new NewServer();
            server.Name       = Guid.NewGuid().ToString();
            server.AccessIPv4 = "0.0.0.0";
            server.FlavorRef  = this.TestFlavorId;
            server.ImageRef   = this.TestImageId;

            IServerRepository repository = this.Factory.CreateServerRepository();
            Server result                = repository.SaveServer(server);

            // Delete it and test.

            repository.DeleteServer(result.Id);
            Thread.Sleep(15000);
            Assert.IsNull(repository.GetServer(result.Id));
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_Reboot()
        {
            IServerRepository repository = this.Factory.CreateServerRepository();
            RebootAction action          = new RebootAction();            
            action.RebootType            = ServerRebootType.HARD;
            action.ServerId              = this.TestServerId;

            repository.Reboot(action);

            Server server = repository.GetServer(this.TestServerId);
            Assert.IsTrue(server.Status == "ACTIVE(rebooting)");
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_GetDetails()
        {
            Server server = this.Factory.CreateServerRepository().GetServer(this.TestServerId);
           
            Assert.IsNotNull(server);
            Assert.IsNotNull(server.Flavor);
            Assert.IsNotNull(server.Image);
        }
//=========================================================================================
/// <summary>
/// 
/// </summary>
//=========================================================================================
        [TestMethod]
        public void Server_GetDetails_ByURI()
        {
            string serverURI = "https://az-1.region-a.geo-1.compute.hpcloudsvc.com/v1.1/58196046451129/servers/" + this.TestServerId;
            Server server    = this.Factory.CreateServerRepository().GetServerByURI(serverURI);

            Assert.IsNotNull(server);
            Assert.IsNotNull(server.Flavor);
            Assert.IsNotNull(server.Image);
        }
        #endregion
    }
}
       